<?php //copyright
include_once('cfg.php');

function base64decode($str){
$x=explode("_",$str);
return openssl_decrypt($x[0], 'AES-128-ECB', $x[1], 0);
}


function check_sign(){global $cfg;
$sign=g('xsign');
$timestep=g('timestep');
$check=md5($cfg['sign'].$timestep);
if($sign!=$check){err('非法的数据传输');}
}


function pm_add($jifen,$shop,$c=''){//排名
global $conn,$cfg;
if(!$jifen){return;}
if(!$shop){return;}
if(!$shop['dist']){return;}
$arr['jifen']=$jifen;
$arr['shop_id']=$shop['id'];
$arr['city']=$shop['dist'];
$arr['c']=$c;
insert($cfg['e'].'pm',$arr);
}


function get_my_temp($title,$hd_id){//获取我的模板
global $conn,$cfg,$user;
$sql='select * from '.$cfg['e'].'temp_msg where  title="'.a($title).'" and is_send=0 and user_id="'.$user['id'].'" ';
if($hd_id){$sql.=' and hd_id="'.$hd_id.'" ';}
$sql.='order by id asc';
$l=db1($sql);
if($l){return $l;}
}



function new_hd(){//全新活动
global $conn,$set,$shop,$user,$err,$cfg;
$arr['state']=0;
$arr['title']='';
$arr['shop_id']=$shop['id'];
$arr['user_id']=$user['id'];
$arr['bg']=$err['bg'][0];
$arr['date']=time();
$arr['start']=get_time(date('Y-m-d H:0:0',time()+1800));
$arr['end']=get_time(date('Y-m-d H:0:0',time()+3600*24*5));
$arr['nickname']=base64($user['nickname']);
$arr['logo']=$user['logo'];
$arr['show_name']=2;
$arr['activity_go']=1;//是否开启
$arr['cps']=$shop['cps_bl'];//默认佣金比例
if(!$arr['cps']){$arr['cps']=0;}
if(!$arr['cps']){$arr['cps']=0;}

//运费模板
if($shop['yun_id']){//获取最后一次的运费模板
$arr['yun_id']=$shop['yun_id'];
$arr['yun_title']=$shop['yun_title'];
}else{
$sql='select * from '.$cfg['e'].'hd where shop_id="'.$shop['id'].'"  and state=1 order by id desc';
$hd=db1($sql);
if($hd){
$arr['yun_id']=$hd['yun_id'];
$arr['yun_title']=$hd['yun_title'];
}
}

if($user['is_emp']){
$arr['emp_id']=$user['id'];
}
$arr['latitude']=$shop['latitude'];$arr['longitude']=$shop['longitude'];
if(!$arr['latitude']){$arr['latitude']=g('latitude');$arr['longitude']=g('longitude');}

$id=insert($cfg['e'].'hd',$arr);sql_error();
return $id;
}


function jifen($jifen,$user_id,$c='购物',$info=''){//用户积分
global $cfg,$conn,$set;
if($jifen==0){return;}
if(!$user_id){return;}
$arr['jifen']=$jifen;
$arr['user_id']=$user_id;
$arr['date']=time();
$arr['c']=$c;$arr['info']=$info;
$arr['state']=0;
$id=insert($cfg['e'].'jifen',$arr);
if($id){
$sql='update '.$cfg['e'].'users set jifen=jifen+'.$jifen.' where id="'.$user_id.'"';
sql_query($sql);
}}


function order_finish($order){//订单完成
global $conn,$cfg,$set,$user,$shop;
$re=order_jiesuan($order);//结算
if($re!='ok'){err($re);}
//是否进行分佣金
if($order['cps_bl']>0 and $order['from_id']){
if(!$order['cps_order_no']){
$money=number_format($order['pro_price']*$order['cps_bl'],2,'.','');
if($cfg['debug']){$money=number_format($order['pay_price']*$order['cps_bl']/100,2,'.','');}
$tz=get_user($order['from_id'],1);
if($tz){
if($order['profit_sharing']){//如果是分账模式
pay_user_add($tz);//添加分账用户
if(!$money or $money<0.01){$money=0.01;}//最低金额
$d[]=array("type"=>"PERSONAL_OPENID","account"=>$tz['openid'],"amount"=>$money*100,"description"=> "佣金收入");
//print_r($d);
$re=fenzhang($order,$d);//分账
//分账完成
$zd['date']=time();
$zd['order_id']=$order['id'];
$zd['shop_id']=$shop['id'];
$zd['title']='佣金支出';
$zd['user_id']=$tz['id'];
$zd['c']='cps';
$zd['money']=-$money;
$zd['nickname']=base64_encode($tz['nickname']);
$zd['logo']=$tz['logo'];
insert($cfg['e'].'pay',$zd);
zd_balance($shop);//账单结算
}else{//非分账模式，账单直接到待支付佣金中
$arr['shop_id']=$shop['id'];
$arr['order_id']=$order['id'];
$arr['user_id']=$user['id'];
$arr['state']=0;
$arr['date']=time();
$arr['c']='cps';
$arr['title']='佣金支付';
$arr['money']=$money;
$arr['openid']=$tz['openid'];
$arr['nickname']=base64_encode($tz['nickname']);
$arr['logo']=$tz['logo'];
$arr['pay_method']=$order['cps_pay'];
insert($cfg['e'].'need_pay',$arr);
}
}}}

if($order['profit_sharing']){
$re=pay_finlish($order);//订单分账完成
}


$arr['state']=10;
$arr['finish_date']=time();
//用户积分
if($set['buy_jifen']>0){
$jifen=ceil($order['pay_price']*$set['buy_jifen']);
jifen($jifen,$order['user_id'],'购物','订单号:'.$order['id']);
}

update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');
pm_add(3,$shop,'订单完成');
//发货信息录入
//upload_shipping_info($order);
//发送消息
$temp=get_my_temp('订单完成通知', $order['hd_id']);
//配送通知推送
if($temp){
$data['template_id']=$temp['temp_id'];
$data['page']='/pages/order/index';
$data['openid']=$user['openid'];
$data['data']=array(
'character_string2'=>array('value'=>$order['id']),
'thing1'=>array('value'=>$shop['shop_name']),
'amount3'=>array('value'=>$order['total']),
'time4'=>array('value'=>date('Y-m-d H:i:s',$order['pay_date'])),
'date7'=>array('value'=>date('Y-m-d H:i:s',time())),
);

$re=min_msg($data);
if($re['errmsg']=='ok'){
$arrs['is_send']=1;
update($cfg['e'].'temp_msg',$arrs,' where id="'.$temp['id'].'"');
}else{
return $re['errmsg'];
}
}


}




function pay_user_add($user){//添加分账用户
global $cfg,$user,$set;
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);
$wx['mch_id']=$set['mch_id'];
$wx['appid']=$cfg['wx_xcx_appid'];
$wx['nonce_str']=time();
$wx['sign_type']='HMAC-SHA256';
$receiver=array('type'=>'PERSONAL_OPENID','account'=>$user['openid'],'relation_type'=>'USER');
$wx['receiver']=json_encode($receiver);
$stringSignTemp = $wechatAppPay->SHA256($wx);
$wx['sign'] = $stringSignTemp;
$xml_data = $wechatAppPay->data_to_xml($wx);

$path=pem();
$data =curl_post_ssl('https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver',$xml_data,$path.'_cert.pem',$path.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);  
if($res['return_code']=='SUCCESS'){//错误
if($res['result_code']=='SUCCESS'){//分账用户添加成功
return 'ok';
}else{//错误
err($res['err_code_des']);
}
}else{err($res['return_msg']);}
//print_r($res);
}



function pay_finlish($order){//支付佣金 分账
global $cfg,$conn,$set;
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);
$wx['mch_id']=$set['mch_id'];
$wx['appid']=$cfg['wx_xcx_appid'];
$wx['nonce_str']=time();
$wx['sign_type']='HMAC-SHA256';
$wx['transaction_id']=$order['transaction_id'];
$wx['out_order_no']=time().rand(0,1000);
$wx['description']='订单分账完成';
$stringSignTemp = $wechatAppPay->SHA256($wx);
$wx['sign'] = $stringSignTemp;
$xml_data = $wechatAppPay->data_to_xml($wx);

$path=pem();
$data =curl_post_ssl('https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish', $xml_data,$path.'_cert.pem',$path.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);
if($res['return_code']=='SUCCESS'){
if($res['result_code']=='SUCCESS'){
$arr['is_fz']=$wx['out_order_no'];//是否分账
update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');
return 'ok';
}else{err($res['err_code_des']);}
}else{err($res['return_msg']);}
}


function fenzhang($order,$d){//分账给用户
global $cfg,$set,$conn;
if(!$d){err('没有找到分账用户');}
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);
$wx['mch_id']=$set['mch_id'];
$wx['appid']=$cfg['wx_xcx_appid'];
$wx['nonce_str']=time();
$wx['sign_type']='HMAC-SHA256';
$wx['transaction_id']=$order['transaction_id'];
$wx['out_order_no']=time().rand(0,1000);
//$u[]=array("type"=>"PERSONAL_OPENID","account"=>"on7k95NJKgU8X1sud-cD_0_j0K5o","amount"=>5,"description"=> "分到用户");

$wx['receivers']=json_encode($d);
$stringSignTemp = $wechatAppPay->SHA256($wx);
$wx['sign'] = $stringSignTemp;
$xml_data = $wechatAppPay->data_to_xml($wx);   

$path=pem();
$data =curl_post_ssl('https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing', $xml_data,$path.'_cert.pem',$path.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);

if($res['return_code']=='SUCCESS'){
if($res['result_code']=='SUCCESS'){
$arr['cps_order_no']=$wx['out_order_no'];//是否分账
$arr['cps_pay_date']=time();
update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');
return 'ok';
}else{err($res['err_code_des']);}
}else{err($res['return_msg']);}

}



function get_temp($c){//获取模板
global $conn,$cfg,$redis;
if($redis){
$temp=$redis->get('temp_'.$c);
if($temp){$temp=unserialize(out($temp));}
if($temp and is_array($temp)){return $temp;}
}
$sql='select * from '.$cfg['e'].'temps where s="'.$c.'" and c="user" and state=1 order by o desc,id asc limit 3';
$temps=db($sql);
if($temps){
foreach($temps as $v){
$temp[]=$v['temp_id'];
}

}
if($redis){
r_set('temp_'.$c,$temp,600);
}
return $temp;
}

//发货信息录入接口
function upload_shipping_info($order,$transaction_id,$user_info){
    //发货信息录入接口
    global $cfg,$set,$adm,$redis;
    if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
        $token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']);
    }else{//print_r($app);
//$token=get_token($app);
    }

    if(!$token){err('获取验证码失败');}
    $url='https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token='.$token;

    //查询本单用户
    $options['order_key'] = array('order_number_type'=>2,'transaction_id'=>$transaction_id);
    $options['delivery_mode'] = 1;
    $options['logistics_type'] = 4;
    $shiping_list =array(
        "item_desc"=> base64($order['hd_title']),
    );
    $options['shipping_list'][] = $shiping_list;
    $options['upload_time'] = date('Y-m-d\TH:i:sP');
    $options['payer'] = array('openid'=>$user_info['openid']);

// 强制转换所有字符串为 UTF-8
    array_walk_recursive($options, function (&$value) {
        if (is_string($value)) {
            $value = mb_convert_encoding($value, 'UTF-8', 'auto');
        }
    });

// 生成 JSON（禁用 Unicode 转义）
    $data = json_encode($options,JSON_UNESCAPED_UNICODE);
    $return = send_post( $url, $data);
    return $return;
}

function update_activity_msg($hd){
global $conn,$cfg,$set,$conn;
if(!$hd['activity_id']){return;}
if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
$token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']); 
}else{//print_r($app);
//$token=get_token($app);
}
if(!$token){return;}
$url='https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send?access_token='.$token;

$data['activity_id']=$hd['activity_id'];
$data['target_state']=0;
$parameter_list[]=array('name'=>'member_count','value'=>$hd['order_num']);
$parameter_list[]=array('name'=>'room_limit','value'=>$hd['view']);
$data['template_info']=array('template_id'=>'21B034D08C5615B9889CE362BB957B1EE69A584B','parameter_list'=>$parameter_list);
$data=json_encode($data,1);
$re=send_post( $url,$data);
//print_r($re);
}



function get_activity_id($hd){//活动消息模板
global $conn,$cfg,$set,$conn;
if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
$token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']); 
}else{//print_r($app);
//$token=get_token($app);
}

if(!$token){return;}
$url='https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token='.$token;
$data =''; 
$data = send_post( $url,$data);
if(!$data){return;}
$data=json_decode($data,1);
if($data['errcode']==0){
$arr['activity_id']=$data['activity_id'];
$arr['activity_out']=$data['expiration_time']-3600;
update($cfg['e'].'hd',$arr,' where id="'.$hd['id'].'"');
}
}



function logo_img($img){
global $cfg;
list($width,$height,$type,$attr) = getimagesize($img);
$img_w=750;$img_h=750;
$im = @imagecreatetruecolor($img_w,$img_h) or die("图片创建失败");//创建图片
switch($type){
default:$source=imagecreatefromjpeg($img);break;
case 3:$source=imagecreatefrompng($img);break;
case 18:$source=imagecreatefromwebp($img);break;
}



if(!$source){return;}
$background_color = imagecolorallocate($im,255, 255,255);
imagefill($im,0,0,$background_color);

if($width>$height){
$left=ceil(($width-$height)/2);$top=0;$w=$height;
}else{
$top=ceil(($height-$width)/2);$left=0;$w=$width;
}
imagecopyresized($im,$source,0,0,$left,$top,$img_w,$img_h,$w,$w);
switch($type){
default:imagejpeg($im,$img,80);break;
case 3:imagepng($im,$img);break;
case 18:imagewebp($im,$img,80);break;
}

}



function set_share_img($hd){//设置活动分享主图
global $cfg,$shop;
$img=get_img($hd['img'],'_750');
list($width,$height,$type,$attr) = getimagesize($img);
$img_w=750;$img_h=600;//图片尺寸
$im = @imagecreatetruecolor($img_w,$img_h) or die("图片创建失败");//创建图片
switch($type){
default:$source=imagecreatefromjpeg($img);break;
case 3:$source=imagecreatefrompng($img);break;
case 18;$source=imagecreatefromwebp($img);break;
}



if(!$source){return;}
$background_color = imagecolorallocate($im,255, 255,255);
imagefill($im,0,0,$background_color);
$bl=$height/$width;

if($bl<0.8){//横图
$w=$width/0.8;
$left=ceil(($width-$w)/2);
imagecopyresized($im,$source,0,0,$left,0,$img_w,$img_h,$w,$height);//防止图片
}else{
$h=ceil($width*0.8);

$top=ceil(($height-$h)/2);
imagecopyresized($im,$source,0,0,0,$top,$img_w,$img_h,$width,$h);//防止图片
}
//画矩形
$stamp = imagecreatetruecolor(750,80);
imagefilledrectangle($stamp,0,0, 750, 80, 0xFFFFFF);
imagecopymerge($im,$stamp,0,520, 0, 0,750,80, 50);

//图标
list($width,$height,$type,$attr) = getimagesize($shop['logo']);
$logo=yuan($shop['logo']);
imagecopyresized($im,$logo,30,530,0,0,60,60,$width,$width);
$font='./font/font.ttf';
$text_color=imagecolorallocatealpha($im,0,0,0,0);
imagettftext($im,30,0,110,573,$text_color,$font,$shop['shop_name']);
imagettftext($im,30,0,111,574,$text_color,$font,$shop['shop_name']);

//添加秒杀图


if($hd['miao_price'] and $hd['miao_pro']){
$img='./image/ms.png';
list($width,$height,$type,$attr) = getimagesize($img);
$source=imagecreatefrompng($img);
imagecopyresized($im,$source,530,20,0,0,200,200,$width,$height);//防止图片
}else{//满赠
if($hd['mz_price'] and $hd['mz_pro']){
$img='./image/zp.png';
list($width,$height,$type,$attr) = getimagesize($img);
$source=imagecreatefrompng($img);
imagecopyresized($im,$source,530,20,0,0,200,200,$width,$height);//防止图片
}
}


$path='./cache/';
if(!file_exists($path)){mkdir($path);}
$path=$path.'hb/';
if(!file_exists($path)){mkdir($path);}
$file=$path.$hd['id'].'.png';

imagepng($im,$file);


}



function yuan($imgpath) {//圆角图
        $ext     = pathinfo($imgpath);
        $src_img = null;
       //echo $imgpath;
        switch ($ext['extension']) {
            case 'jpg'://echo 'aaa';
                $src_img = imagecreatefromjpeg($imgpath) or die('图片创建失败');
                break;
            case 'png':
                $src_img = imagecreatefrompng($imgpath);
                break;
            case 'webp':
                $src_img = imagecreatefromwebp($imgpath);
                
                break;
                default:
               $src_img = imagecreatefromjpeg($imgpath);     
                    break;
        }
         //print_r($src_img.' '.$imgpath);
        $wh  = getimagesize($imgpath);
        $w   = $wh[0];
        $h   = $wh[1];
        $w   = min($w, $h);
        $h   = $w;
        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);
        $r   = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($src_img, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
        return $img;
    }

function get_user($user_id,$ac=0){
global $conn,$cfg,$redis;
if($redis){
$u=$redis->get($cfg['path'].'user_'.$user_id);
if($u){$u=unserialize($u);if($u){
if(!$ac){unset($u['openid'],$u['session']);}
return $u;}else{unset($u);}}
}

$sql='select * from '.$cfg['e'].'users where id="'.$user_id.'" ';
$l=db1($sql);
if(!$l){return;}
$l['nickname']=base64($l['nickname']);
if($redis){r_set($cfg['path'].'user_'.$user_id,'',600);}
if(!$ac){unset($l['openid'],$l['session']);}
return $l;
}



function money_pay_bank($total,$trade_no,$bank,$c='提现到银行卡',$repeat_pay=1){//金额支付到用户/提现到零钱
global $conn,$user,$cfg,$set;
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);
$param['mch_appid'] = $cfg['wx_xcx_appid'];
$param['mchid'] = $set['mch_id'];
$param['nonce_str'] = md5(time());
$param['openid'] = $user['openid'];
$param['partner_trade_no'] =$trade_no;
$param['enc_bank_no'] = $bank['enc_bank_no'];//需要加密
$param['enc_true_name'] =$bank['enc_true_name'];
$param['bank_code'] =$bank['bank_code'];

$param['check_name']='NO_CHECK';
$param['amount'] = $total*100;
$param['desc'] =$c;
$param['spbill_create_ip'] =$_SERVER['REMOTE_ADDR'];
$stringSignTemp = $wechatAppPay->MakeSign($param);
$param['sign'] = $stringSignTemp;
$xml_data = $wechatAppPay->data_to_xml($param);

    //查找退款密匙
    $path='./cert/';
    if(!file_exists($path)){mkdir($path,0700);}
    $file=md5('key');
    if(!file_exists($path.$file.'_cert.pem') or !file_exists($path.$file.'_key.pem')){
    if(!$set['cert_pem'] or !$set['key_pem']){err('抱歉，您的退款密匙出错，请联系管理员进行处理');}
    save_file($path,$file.'_cert.pem',$set['cert_pem']);
    save_file($path,$file.'_key.pem',$set['key_pem']);
    }

$data =curl_post_ssl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $xml_data, $path.$file.'_cert.pem',$path.$file.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);
//print_r($res);

if($res['return_code']=='SUCCESS'){
if($res['result_code']=='SUCCESS'){
$re['payment_no']=$res['payment_no'];
$re['cmms_amt']=$res['cmms_amt'];//手续费金额
return $re;

}else{
if($res['err_code']=='SYSTEMERROR'){//重复
if($repeat_pay==1){//重复一次支付，如果出错，则返回错误
money_pay_user($total,$trade_no,$c,0);
}else{
err('订单支付错误，如有问题请联系我们。');
}
}else{err($res['err_code'].' '.$res['err_code_des']);}
}
}else{err($res['return_msg']);}
}



function money_pay_user($total,$trade_no,$c='提现到零钱',$repeat_pay=1){//金额支付到用户/提现到零钱
global $conn,$user,$cfg,$set;
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);
$param['mch_appid'] = $cfg['wx_xcx_appid'];
$param['mchid'] = $set['mch_id'];
$param['nonce_str'] = md5(time());
$param['openid'] = $user['openid'];
$param['partner_trade_no'] =$trade_no;
$param['check_name']='NO_CHECK';
$param['amount'] = $total*100;
$param['desc'] =$c;
$param['spbill_create_ip'] =$_SERVER['REMOTE_ADDR'];
$stringSignTemp = $wechatAppPay->MakeSign($param);
$param['sign'] = $stringSignTemp;
$xml_data = $wechatAppPay->data_to_xml($param);


    $path=pem();

//    $data =curl_post_ssl('https://api.mch.weixin.qq.com/secapi/pay/refund',$xml_data,$path.'_cert.pem',$path.'_key.pem');


    //查找退款密匙
//    $path='./cert/';
//    if(!file_exists($path)){mkdir($path,0700);}
//    $file=md5('key');
//    if(!file_exists($path.$file.'_cert.pem') or !file_exists($path.$file.'_key.pem')){
//    if(!$set['cert_pem'] or !$set['key_pem']){err('抱歉，您的退款密匙出错，请联系管理员进行处理');}
//    save_file($path,$file.'_cert.pem',$set['cert_pem']);
//    save_file($path,$file.'_key.pem',$set['key_pem']);
//    }
    $path=pem();

$data =curl_post_ssl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $xml_data, $path.$file.'_cert.pem',$path.$file.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);
//print_r($res);

if($res['return_code']=='SUCCESS'){
if($res['result_code']=='SUCCESS'){
$re['err']='ok';
$re['partner_trade_no']=$res['partner_trade_no'];
$re['payment_no']=$res['payment_no'];
$re['payment_time']=$res['payment_time'];
return $re;

}else{
if($res['err_code']=='SYSTEMERROR'){//重复
if($repeat_pay==1){//重复一次支付，如果出错，则返回错误
money_pay_user($total,$trade_no,$c,0);
}else{
err('订单支付错误，如有问题请联系我们。');
}
}else{err($res['err_code'].' '.$res['err_code_des']);}
}
}else{err($res['return_msg']);}
}




function get_qr($d){//获取小程序二维码
global $cfg,$set,$adm,$redis;
if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
$token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']); 
}else{//print_r($app);
//$token=get_token($app);
}

if(!$token){err('获取验证码失败');}
$url='https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.$token;
$data = json_encode($d,true); 
$return = send_post( $url, $data);

return $return;
}



function msg_check($text,$c='text'){//消息鉴别黄色
global $conn,$cfg,$user;
$token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']); 
if(!$token){return '数据错误';}
if($c=='text'){
$url='https://api.weixin.qq.com/wxa/msg_sec_check?access_token='.$token;
$data['version']=2;
$data['openid']=$user['openid'];
$data['scene']=3;
$data['content']=$text;
//print_r($data);
$data = json_encode($data); 
//$data['nickname']=$user['nickname'];
$re=send_post($url,$data);
$re=json_decode($re,1);

if($re['errcode']==0){
if($re['result']['suggest']!='pass'){
echo $re['result']['label'];
}

}else{
err($re['errmsg']);
}
}else{
$url='https://api.weixin.qq.com/wxa/media_check_async?access_token='.$token;

}



}




function get_gz($shop_id,$page=1,$page_num=10){//获取最新关注者
global $conn,$cfg,$redis;
if($redis){
$list=$redis->get('gz_list_'.$shop_id);
if($list){
$list=unserialize(out($list));
if($list and is_array($list)){return $list;}
}
}

$start=($page-1)*$page_num;
$sql='select id,user_id,logo,need_post from '.$cfg['e'].'shop_gz where shop_id="'.$shop_id.'" order by id desc limit '.$start.','.$page_num;
$l=db($sql);
if($l){
foreach($l as $v){
if($v['logo']){

$list['item_'.$v['id']]=$v;
}
}
krsort($list);
}
if($redis){
r_set('gz_list_'.$shop_id,$list,600);
}
return $list;

}




function order_jiesuan($order){//订单结算，进行结算和cps结算
global $conn,$cfg,$set,$shop;
if($order['js_date']>0){return 'ok';}

$pay=number_format($order['pay_price']/100,2,'.','');
//1，计算订单的平台佣金
if(!$set['jiesuan']){$set['jiesuan']=$cfg['jiesuan'];}
if(!$set['jiesuan']){$set['jiesuan']=0;}
$pintai_fei=number_format($order['pay_price']*$set['jiesuan']/100,2,'.','');;
if($pintai_fei<0.01){$pintai_fei=0.01;}
//账单
$zd['shop_id']=$shop['id'];
$zd['title']='订单结算';
$zd['user_id']=$shop['user_id'];
$zd['c']='结算';
$zd['date']=time();
$zd['money']=-$pintai_fei;
$zd['order_id']=$order['id'];
insert($cfg['e'].'pay',$zd);


$arr['js_date']=time();
update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');

return 'ok';
}




function zd_balance($shop){//对订单和门店进行余额统计//$is_pay是否支付，进行
global $conn,$cfg;
$sql='select * from '.$cfg['e'].'pay where shop_id="'.$shop['id'].'" and state=0 order by id asc';
$l=db($sql);
if($l){
$sql='select * from '.$cfg['e'].'pay where shop_id="'.$shop['id'].'" and state=1 order by id desc limit 1';
$n=db1($sql);
$money=0;$cps=0;
if($n){$balance=$n['balance'];}else{$balance=0;}
$arr['balance']=$balance;
foreach($l as $v){
$arr['balance']=$arr['balance']+$v['money'];
$arr['state']=1;
update($cfg['e'].'pay',$arr,' where id="'.$v['id'].'"');

switch($v['c']){
case 'pay':$money+=$v['money'];break;//支付的金额
case 'cps':
  $cps+=-$v['money'];  
  $cps_user[$v['user_id']]+=-$v['money'];
break;//佣金支出
}


}

$shop_arr['balance']=$arr['balance'];
$shop_arr['order_price']=$shop['order_price']+$money;//订单金额
$shop_arr['cps_pay']=$shop['cps_pay']+$cps;//支付的佣金
update($cfg['e'].'shop',$shop_arr,' where id="'.$shop['id'].'"');

//用户的cps账户
if($cps_user){
foreach($cps_user as $k=>$v){
if($k){
$sql='update '.$cfg['e'].'users set cps_balance=cps_balance+'.$v.' where id="'.$k.'"';
sql_query($sql);
}
}
}


}
}

function pem(){
    global $set;
    $path='./cert/';
    if(!file_exists($path)){mkdir($path,0700);}
    $file=md5($set['pem_name']);
    if(!file_exists($path.$file.'_cert.pem') or !file_exists($path.$file.'_key.pem')){
    if(!$set['cert_pem'] or !$set['key_pem']){err('抱歉，您的支付密匙出错，请联系管理员进行处理');}
    save_file($path,$file.'_cert.pem',$set['cert_pem']);
    save_file($path,$file.'_key.pem',$set['key_pem']);
    }
    return $path.$file;
}

function tuikuan($order,$arr){//退款
    global $conn,$cfg,$set;
$wechatAppPay = new wechatAppPay($cfg['wx_xcx_appid'], $set['mch_id'], '', $set['pay_key']);

        $param['appid'] = $cfg['wx_xcx_appid'];
        $param['mch_id'] = $set['mch_id'];
        $param['nonce_str'] = md5(time());
        $param['out_trade_no'] = $order['out_trade_no'];
        $param['out_refund_no'] = $arr['out_refund_no'];

            $param['total_fee'] = $arr['tui_pirce'];
            $param['refund_fee'] =$arr['tui_pirce'];
//            $param['refund_desc'] = $order['id'].'订单退款';
            $param['refund_desc'] = $order['id'];
            $stringSignTemp = $wechatAppPay->MakeSign($param);
            $param['sign'] = $stringSignTemp;
//print_r($param);
            $xml_data = $wechatAppPay->data_to_xml($param);
    //查找退款密匙
$path=pem();
    
$data =curl_post_ssl('https://api.mch.weixin.qq.com/secapi/pay/refund',$xml_data,$path.'_cert.pem',$path.'_key.pem');
$res = $wechatAppPay->xml_to_data($data);
if(!$res){err('退款失败');}
if($res['return_code']=='SUCCESS'){
if($res['result_code']=='SUCCESS'){//退款成功
return 'ok';
}else{
err($res['err_code_des']);//操作失败
}
    

}else{err($res['return_msg']);}//操作失败


}



function get_url($d){//获取url码
global $cfg,$set,$redis;
if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
$token=getAccessToken($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']); 
}else{//print_r($app);
//$token=get_token($app);
}
if(!$token){return '获取验证码失败';}
$url='https://api.weixin.qq.com/wxa/generate_urllink?access_token='.$token;
$data = json_encode($d,true); 
$return = send_post( $url, $data);
return $return;
}



function wlog($data){
global $user,$cfg,$conn,$shop;
$arr=$data;
if($shop){$arr['shop_id']=$shop['id'];}
$arr['user_id']=$user['id'];$arr['date']=time();
insert($cfg['e'].'log',$arr);
}


function pay($total,$d=[]){
global $cfg,$order,$user,$shop,$set,$hd;
$wx['appid']=$cfg['wx_xcx_appid'];
$wx['mch_id']=$set['mch_id'];
$wx['nonce_str']=time();
$wx['sign_type']='MD5';
if($d['body']){
$wx['body']=$d['body'];
}else{
$wx['body']='['.$hd['title'].' 付款';
}
$wx['out_trade_no']=$order['id'].'_'.time();
if($d['out_trade_no']){$wx['out_trade_no']=$d['out_trade_no'];}else{$wx['out_trade_no']=$order['id'].'_'.time();}

$wx['total_fee']=$total;
$wx['spbill_create_ip']=$_SERVER['REMOTE_ADDR'];

if($d['notify_url']){//回调地址
$wx['notify_url']=$d['notify_url'];
}else{
$wx['notify_url']=$cfg['notify_url'];//接龙支付返回页面
}


$wx['trade_type']='JSAPI';
$renzhen=md5($order['id'].$order['date'].$order['user_id'].'8888');
$wx['attach']=$order['id'].'_'.$renzhen;

if(!$d['time_expire']){$d['time_expire']=date('YmdHis',time()+60*5);}
$wx['time_expire']=$d['time_expire'];



$wx['openid']=$user['openid'];
if($set['profit_sharing']){$wx['profit_sharing']='Y';}//开启分账模式
//$wx['profit_sharing']='Y';
//print_r($wx);exit;
ksort($wx);
//排序
foreach($wx as $k=>$v){
$xx.=$k.'='.$v.'&';
}
$xx.='key='.$set['pay_key'];
$sign=strtoupper(md5($xx));
$wx_url='https://api.mch.weixin.qq.com/pay/unifiedorder?';
$wx['sign']=$sign;
$xml=data_to_xml($wx);
$wx_re=postXmlCurl($wx_url,$xml);
if(!$wx_re){err('微信支付出错，请联系管理员');}//支付错误
$re=xml_to_data($wx_re);
if($re['err_code_des']){
err($wx['appid'].$re['err_code_des']);
}

if($re['return_code']=='SUCCESS'){//发起小程序支付
$data['prepay_id']=$re['prepay_id'];
$xcx['appId']=$wx['appid'];
$xcx['timeStamp']=md5(time());
$xcx['nonceStr']=md5(time());
$xcx['package']='prepay_id='.$re['prepay_id'];
$xcx['signType']='MD5';
ksort($xcx);
$xx='';
foreach($xcx as $k=>$v){
$xx.=$k.'='.$v.'&';
}

$xx.='key='.$set['pay_key'];
$xcx['paySign']=strtoupper(md5($xx));
}else{
err($re['return_msg']);
}
//$err['pay']=$xcx;
return $xcx;

}











function get_l($addr){//获取地图地址
global $set;
$map_key=$set['map_key'];
$url='https://apis.map.qq.com/ws/geocoder/v1/?address='.$addr.'&key='.$map_key;
$body=file_get_contents($url);
if(!$body){return;}
$arr=json_decode($body,1);
if($arr['message']=='query ok'){
$o['latitude']=$arr['result']['location']['lat'];
$o['longitude']=$arr['result']['location']['lng'];
return $o;
}
}

function get_zt($latitude,$longitude){
global $cfg,$conn,$shop,$set,$user,$redis,$yun;

if($yun['zt_addr']){
$sql='select * from '.$cfg['e'].'addr where id in ('.$yun['zt_addr'].'0) order by id desc';

$l=db($sql);
if($l){
if($latitude){
foreach($l as $v){
if($v['latitude']){
$dis=get_dis($longitude,$latitude, $v['longitude'],$v['latitude'],1,1);

if($dis>1000){
$v['dis']=number_format($dis/1000,2,'.','').'千米';
}else{
$v['dis']=$dis.'米';
}

$x[$dis][]=$v;
}else{
$x['no'][]=$v;
}
}
ksort($x);
foreach($x as $t){
foreach($t as $v){
$list['item_'.$v['id']]=$v;
}
}
    
}else{//没有获取到位置
foreach($l as $v){
$list['item_'.$v['id']]=$v;
}

}


}

}
//print_r($list);
return $list;
}



function get_yun($yun,$order){//获取运费信息
global $cfg,$conn,$shop,$set,$user,$redis;
$o['err']='ok';$o['yun_id']=$yun['id'];
//自提
if($order['yun']=='is_zt'){$o['yun_price']=0;
//如果可以获取定位
$latitude=g('latitude');$longitude=g('longitude');
//自提点
$o['latitude']=$latitude;
$o['longitude']=$longitude;

$zt_addr=get_zt($latitude,$longitude);
if($zt_addr){//存在自提
if($order['zt_addr']){$zt=$zt_addr['item_'.$order['zt_addr']];}
if(!$zt){
if($user['zt_addr']){$zt=$zt_addr['item_'.$user['zt_addr']];$save=1;}//用户的自提点
}
if(!$zt){$zt=current($zt_addr);$save=1;}//如果还没有找到，则获取第一个作为自提点

$o['ztd']=$zt_addr;//列表
$o['zt_addr']=$zt['id'];

$o['dis']=$zt['dis'];
$o['zt']=$zt;

if($save==1){//保存到门店
$arr['zt_addr']=$zt['id'];
update($cfg['e'].'users',$arr,' where id="'.$user['id'].'"');
$arr['shop_name']=$zt['title'];
$arr['shop_addr']=$zt['addr'];
$arr['pro']=$zt['pro'];$arr['city']=$zt['city'];$arr['dist']=$zt['dist'];
//$arr['shop_phone']=$zt['phone'];
update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');
}


}else{//没有设置自提点，则选择门店作为自提点
//如果保存了自提点 但是没有自提点数据了
if($order['zt_addr']>0){
$arr['zt_addr']=0;
update($cfg['e'].'order',$arr,' where id="'.$order['id'].'"');
}

if($latitude and $longitude and $shop['latitude']){
$dis=get_dis($longitude,$latitude, $shop['longitude'], $shop['latitude'],1,1);//活动距离
$o['dis']=$dis;
}
}

return $o;}//自提

if($order['yun']=='is_ps'){//配送
if($shop['latitude'] and $order['latitude']){//如果门店设置了经纬度，则尽量获取客户距离
$dis=get_dis($order['longitude'],$order['latitude'], $shop['longitude'], $shop['latitude'],1,1);
}else{
if($order['pro'] and $order['addr']){//存在地址
$ll=get_l($order['pro'].$order['city'].$order['dist'].$order['addr']);//获取经纬度
if($ll){
$o['latitude']=$ll['latitude'];
$o['longitude']=$ll['longitude'];
$order['latitude']=$ll['latitude'];$order['longitude']=$ll['longitude'];
if($shop['latitude']){
$dis=get_dis($order['longitude'],$order['latitude'], $shop['longitude'], $shop['latitude'],1,1);
}
}//}

}

}//计算距离

if(!$dis){$dis=0;}

$o['yun_price']=$yun['ps_yun'];//初始运费
//城市
if($yun['city'] and $order['dist']!=$yun['city']){
$o['err_msg']='抱歉，本订单仅限'.$yun['city'].'同城配送。';
//$o['err']='';
return $o;
}

if($yun['ps_num']>0 and $order['num']<$yun['ps_num']){//查找是否满足配送要求
$o['err_msg']='抱歉，本活动满'.$yun['ps_num'].'才可以配送，您可以选择自提或者快递。';
//$o['err']='';
return $o;
}

if($yun['ps_price']>0 and $order['price']<$yun['ps_price']){//查找是否满足配送要求
$o['err_msg']='抱歉，满'.$yun['ps_price'].'元才可以配送,您可以选择到店自提。';
//$o['err']='';
return $o;
}

if($yun['ps_max']>0){//是否超过最大配送距离
if($dis>$yun['ps_max']*1000){
$o['err_msg']='抱歉，您的订单距离超过最远配送范围，您可以选择自提或者快递，如有问题，请联系我们。';
//$o['err']='';
return $o;
}
}

//包邮
if($yun['ps_baoyou']>0 and $order['price']>=$yun['ps_baoyou']){
$o['yun_price']=0;return $o;
}

if($yun['ps_pre_price']>0 and $dis>0){//配送
if(!$yun['ps_min']){$yun['ps_min']=3;}//默认距离
$jl=floor(($dis/1000)-$yun['ps_min']);//计算超过的距离
if($jl>0){
$o['yun_price']=$o['yun_price']+$yun['ps_pre_price']*$jl;
}
}

return $o;
}//配送 

if($order['yun']=='is_kd'){//快递
$o['yun_price']=$yun['kd_price'];

if($yun['kd_baoyou']>0 and $order['price']>=$yun['kd_baoyou']){
$o['yun_price']=0;return $o;
}

//快递数量递增
if($yun['kd_min_num']>0 and $yun['kd_pre_price']>0){
$num=$order['num']-$yun['kd_min_num'];
if($num>0){
$o['yun_price']=$o['yun_price']+$yun['kd_min_num']*$num;
}
}

//更多城市数据
if($yun['data']){
$data=unserialize(out($yun['data']));




}

}
return $o;
}





function get_yun_info($yun){//取得运费信息
if($yun['is_zt']){$h.='支持自提 ';}
if($yun['is_ps']){
if($yun['city']){
$h.=$yun['city'].'同城';
}
if($yun['ps_yun']==0){
$h.='免费配送 ';
}else{
$h.='配送费￥'.$yun['ps_yun'].',';
if($yun['ps_num']>0){$h.=$yun['ps_num'].'件起送,';}
if($yun['ps_price']>0){$h.=$yun['ps_price'].'元起送,';}
if($yun['ps_baoyou']>0){$h.='订单超过'.$yun['ps_baoyou'].'元免配送费,';}
if($yun['ps_pre_price']>0 and $yun['ps_min']>0){
$h.='超过'.$yun['ps_min'].'公里后，每增加1公里增加'.$yun['ps_pre_price'].'元,';
}
}
}else{
$h.='不支持配送 ';
}//配送

if($yun['is_kd']==0){
$h.='不支持快递';
}else{
if($yun['kd_price']==0){$h.='全场包邮';}else{
$h.=' 快递费:'.$yun['kd_price'].'元';
if($yun['kd_baoyou']>0){$h.=',满'.$yun['kd_baoyou'].'包邮.';}

if($yun['kd_pre_price']>0 and $yun['kd_min_num']){
$h.=',超过'.$yun['kd_min_num'].'件后，每增加1件增加运费'.$yun['kd_pre_price'].'元';
}
}
}
return $h;
}



function get_shop($ac=0){//获取门店
global $conn,$redis,$cfg,$user,$set;

if($user['shop_id']){$has_shop=1;
if($user['shop_state']){//停用门店
$shop_id=$user['shop_id'];
}
}

if(!$shop_id){
if($user['is_emp']){$is_emp=1;
if($user['emp_state']!=0){$shop_id=$user['is_emp'];}
}}

if(!$shop_id){
if(!$has_shop){
if(!$ac){err('no_shop');}
if($set['auto_creat']==1){
$shop_id=creat_shop();//创建新门店
}
}
}
if(!$shop_id and $ac){
$shop['id']=0;
return $shop;
}

if(!$shop_id or !is_numeric($shop_id)){err('抱歉，您还没有创建门店，或者您不是雇员');}
$shop=get_hd_shop($shop_id);
return $shop;
}




function creat_shop(){//创建门店
global $conn,$redis,$cfg,$user;
$arr['shop_name']=base64_encode($user['nickname'].'的小店');

$arr['date']=time();
$arr['adm_id']=$user['id'];$arr['user_id']=$user['id'];
$arr['state']=1;
$arr['phone']=$user['phone'];
$arr['pro']=$user['pro'];
$arr['city']=$user['city'];
$arr['dist']=$user['dist'];
$arr['addr']=$user['addr'];$arr['name']=$user['name'];
$arr['logo']=$user['logo'];
$arr['code']='gz:'.md5(time().$user['id']);
$id=insert($cfg['e'].'shop',$arr);
$arrs['shop_id']=$id;
update($cfg['e'].'users',$arrs,' where id="'.$user['id'].'"');
if($redis){//清理缓存
r_set($cfg['path'].'user_'.$user['id'],'',600);
}
return $id;
}






function get_shops($area,$latitude,$longitude,$key='',$page_num=0){
global $conn,$redis,$cfg;
$sql='select * from '.$cfg['e'].'shop where state=1 ';
if($area){$sql.=' and dist="'.$area.'" ';}
if($key){$sql.=' and shopname like "%'.a($key).'%" ';}
$sql.=' order by id asc limit 200';
$l=db($sql);

if($l){
return shop_latlng($l,$latitude,$longitude,$page_num);
}

}
function shop_latlng($l,$latitude,$longitude,$page=0){//对门店进行距离排序
if(!$latitude){return $l;}
foreach($l as $v){
if($v['lat']){
$dis=get_dis($longitude,$latitude, $v['lng'], $v['lat'], 1,2);

if($dis>1000){$shop_dis=number_format($dis/1000,2,'.','').'千米';}else{$shop_dis=ceil($dis).'米';}
$v['dis']=$shop_dis;
$list[$dis][]=$v;
}

}
   
ksort($list);
$num=0;unset($l);
foreach($list as $t){
foreach($t as $v){
$l[]=$v;$num++;
if($num==$page and $page>0){return $l;}
}
}
   
return $l;
}








function th($arr=[]){
echo '<tr>';
foreach($arr as $v){
echo '<th>'.$v.'</th>';
}
echo '</tr>';
}




function get_set($ac=0){
global $conn,$cfg,$redis;
if($redis){
$set=$redis->get($cfg['path'].'web_set');
if($set){$set=unserialize($set);if($set){return $set;}else{unset($set);}}
}
$sql='select * from '.$cfg['e'].'set where id=1';
$set=db1($sql);
if($set){
if($ac==1){}else{
unset($set['key_pem'],$set['cert_pem']);}
if($set['bg']){$set['bg']=unserialize(out($set['bg']));}
if($set['img']){$set['img']=unserialize(out($set['img']));}
if($set['adv']){$set['adv']=unserialize(out($set['adv']));}
if($set['menu']){$set['menu']=unserialize(out($set['menu']));}
if($set['login_bg']){$set['login_bg']=unserialize(out($set['login_bg']));}
if($set['app_bg']){$set['app_bg']=unserialize(out($set['app_bg']));}
}else{
$arr['id']=1;
insert($cfg['e'].'set',$arr);
}
if($cfg['debug']!=1){r_set($cfg['path'].'web_set',$set,300);}
return $set;
}



function is_login($ac=0){
global $cfg,$conn,$redis,$set;
$user_id=g('user_id');$session=g('session');
$from_id=g('from_id');
if($redis and $ac==0){
$user=$redis->get($cfg['path'].'user_'.$user_id);
if($user){
$user=unserialize(out($user));
if(!$user or !is_array($user)){}else{
if($user['session']==$session){
if($user['cps_lock']<time() and $from_id>0){
if(!$set['cps_time']){$set['cps_time']=30;}
$arr['cps_lock']=time()+3600*24*$set['cps_time'];
$arr['cps_from_id']=$from_id;
update($cfg['e'].'users',$arr,' where id="'.$user['id'].'"');
}    

return $user;}
}
}
}


if(!$user_id or !$session){return;}
$sql='select * from '.$cfg['e'].'users where id="'.$user_id.'" ';
$l=db1($sql);if(!$l){return;}
if($l['session']!=$session){return;}
$l['nickname']=base64($l['nickname']);

if(!$ac){unset($l['openid'],$l['unionid']);
if($l['cps_lock']<time() and $from_id>0){
if(!$set['cps_time']){$set['cps_time']=30;}
$arr['cps_lock']=time()+3600*24*$set['cps_time'];
$arr['cps_from_id']=$from_id;
update($cfg['e'].'users',$arr,' where id="'.$l['id'].'"');

}  

if($redis and $cfg['debug']!=1){
r_set($cfg['path'].'user_'.$user_id,$l,600);
}
}

return $l;
}



function no_login(){die('<script>no_login();</script>');}

function user_login(){
global $cfg,$conn,$redis;
$re['err']='no_login';
$user_id=c($cfg['path'].'_user_id');$session=c($cfg['path'].'_user_session');

if(!$user_id or !$session){return $re;}
$sql='select * from '.$cfg['e'].'users where id=:id and session=:session ';
$p['id']=$user_id;$p['session']=$session;
$l=db1($sql,$p);
if(!$l){return $re;}
if($l['state']==99){$re['err']='抱歉，您已经被禁用，请联系系统管理员';return $re;}
if($l['shop_id']){$re['shop_id']=$l['shop_id'];}else{
$re['shop_id']=$l['is_emp'];
}
$re['err']='ok';
$l['nickname']=base64($l['nickname']);
$re['user']=$l;
return $re;
}



function adm_login($power=[]){
global $cfg,$conn,$redis;$re['err']='no_login';
$user_id=c($cfg['path'].'_adm_id');$session=c($cfg['path'].'_adm_session');
if(!$user_id or !$session){return $re;}

$sql='select * from '.$cfg['e'].'adm where id=:id and session=:session ';
$p['id']=$user_id;$p['session']=$session;
$l=db1($sql,$p);
if(!$l){$re['err']='no_login';return $re;}
if($l['state']==99){$re['err']='抱歉，您已经被禁用，请联系系统管理员';return $re;}
if(!$l['power']){$re['err']='抱歉，您还没有设置相应的权限';return $re;}

$re['err']='ok';
$re['adm']=$l;
return $re;
}


function get_power($p=[]){//获取权限
global $cfg,$conn,$redis,$adm;
if(!$adm){return;}
$sql='select * from '.$cfg['e'].'power where id="'.$adm['power_id'].'" ';
$l=db1($sql);
if(!$l){err('没有设置权限，请先设置权限后继续');}
if(!$l['data']){err('抱歉，权限设置错误，请联系管理员');}
$data=unserialize(out($l['data']));//print_r($data);
if(!$p){if(!$data['管理员']){return '抱歉，您没有操作的权限';}}else{
if($data['管理员']){return;}//如果是管理员
foreach($p as $k=>$v){
if(!$data[$k]){return '抱歉，您没有'.$k.'的权限';}
}
}



}







function redis(){
global $redis;
if(!$redis){
if(class_exists('Redis')){
$redis=new Redis();
$redis->connect('127.0.0.1',6379);
    $redis->auth('wldredis2020');
}
}
return $redis;
}

function r_set($key,$val,$time){
global $redis,$adm;
//if($adm['debug']==1){return;}//是否在调试模式下关闭
if($redis){
if(is_array($val)){$val=serialize($val);}
$redis->set($key,$val);
if($time){$redis->expire($key,$time);}
}
}

function r_get($key,$ac=1){
global $redis,$adm;
if(!$redis){return;}
$list=$redis->get($key);
if(!$list){return;}
if($ac){
$list=unserialize(out($list));
if(!is_array($list)){return;}
}

return $list;
}




function no_data($str=''){//没有数据
global $cfg;
if(!$str){$str='没有找到符合条件的结果';}
echo '<no_data><img src="'.$cfg['img_path'].'no_data.png"></no_data><no_data_text>'.$str.'</no_data_text>';
}



function page(){//页面
global $l,$page_num,$page;
if(!$l and $page<2){return;}
if(!$l){$item_total=0;}else{$item_total=count($l);}

if($page<2 and $item_total!=$page_num){return;}

echo '<page>';
$u='./?'.url_get(['page']);
if(!$page){$page=1;}
if($page>1){echo '<a class=" m icon icon-back" href="'.$u.'page='.($page-1).'"></a>';}
$to=2;

if($item_total!=$page_num){$to=0;}

for($i=-2;$i<=$to;$i++){
$p=$page+$i;
if($p>0){
echo '<a class=" m '.($p==$page?'is_select':'').'" href="'.$u.'page='.$p.'">'.$p.'</a>';
}

}

if($item_total==$page_num and $item_total>0){
echo '<a class=" m icon icon-right" href="'.$u.'page='.($page+1).'"></a>';
}
echo '</page>';
}



function mi($str){//加密
if(!$str){return '';}
$f=substr($str,0,3);
$e=substr($str,-3,3);
return $f.'***'.$e;
}



// 过滤掉emoji表情
function filterEmoji($str)
{$str = preg_replace_callback('/./u',function (array $match) {return strlen($match[0]) >= 4 ? '' : $match[0];},
 $str);
     return $str;
 }




function base64($str,$ac=0){if(!$str){return $str;}
if($ac){return base64_encode($str);}

$is_base64=checkStringIsBase64($str);
if($is_base64==true){$s=base64_decode($str);}

if($s){return $s;}else{return $str;}
}

function checkStringIsBase64($str){
$temp=base64_encode(base64_decode($str));
if($str==$temp){return true;}else{return false;}
}





function arrayToXmlStr($arr) {   //封装xml 
ksort($arr);
foreach($arr as $k=>$v){
    if($v){
$h.='<'.$k.'>'.$v.'</'.$k.'>
';}
}
return '<xml>'.$h.'</xml>';
}

function xmlToArray($xml, $recursive = false )
{
    if (!$recursive){
        $array = simplexml_load_string($xml,"SimpleXMLElement", LIBXML_NOCDATA);
        
    } else  {
        $array = $xml;
    }

    $newArray = array ();
   $array = (array) $array ;

    return $array;
}


function curlPost($Url, $PostRequest, $HTTP_headers)
{
   $ch=curl_init();
   curl_setopt($ch, CURLOPT_URL, $Url);
   // init
   curl_setopt($ch, CURLOPT_HEADER, 0);
   if($HTTP_headers){curl_setopt($ch, CURLOPT_HTTPHEADER, array($HTTP_headers));}
   // headers
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // I don't want headers back from the serrver...
   curl_setopt($ch, CURLOPT_POST, 1) ;
   curl_setopt($ch, CURLOPT_POSTFIELDS, $PostRequest);
   // post data
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
   $result = curl_exec($ch);
   curl_close($ch);
   return $result;
}

function sign($para, $wx_key) {//签名
ksort($para);
foreach($para as $k=>$v){
$str.=$k.'='.$v.'&';
}
$str.='key='.$wx_key;

$sign = strtoupper(md5($str));
//print_r($sign);
  return $sign;
}


function is_gz(){global $cfg,$set,$user;//是否关注公众号
$access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$set['wx_appid']."&secret=".$set['wx_appsecret'];
    $access_msg = json_decode(file_get_contents($access_token));
    $token = $access_msg->access_token;
    $subscribe_msg = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$token&openid=".$user['wx_name'].'';
    $subscribe = json_decode(file_get_contents($subscribe_msg),true);
    //print_r($subscribe);exit;
    return $subscribe;
    $gzxx = $subscribe->subscribe;
return $gzxx;
}

function url_get($no){//页面网址
$g=$_GET;
if($no){
foreach($no as $v){
unset($g[$v]);
}
}

if(!$g){return;}
foreach($g as $k=>$v){
$str.=$k.'='.$v.'&';
}

return $str;
}


function out($str){return stripslashes($str);}

function direct($url){$url="Location: ".$url;header("HTTP/1.1 301 Moved Permanently");header($url); }//页面跳转函数

function g($ac){
//$str=$_POST[$ac];
$str=isset($_POST[$ac]) ? $_POST[$ac] : '';
if(!$str){$str=isset($_GET[$ac]) ? $_GET[$ac] : '';}
return trim($str);}

function get($ac){$str=isset($_GET[$ac]) ? $_GET[$ac] : '';return htmlspecialchars(trim($str));}
function p($ac){$str=isset($_POST[$ac]) ? $_POST[$ac] : '';;return trim($str);}

function s($ac){$str=isset($_SESSION[$ac]) ? $_SESSION[$ac] : '';return trim($str);}
function c($ac){$str=isset($_COOKIE[$ac]) ? $_COOKIE[$ac] : '';return trim($str);}
function a($t){return addslashes($t);}


function err($str){$err['err']=$str;echo json_encode($err);exit;}//输出错误信息

function get_imgs($img){
if(!$img){return;}
$im=explode('||',$img);
foreach($im as $k=>$v){
if($v){
$re[$k]['img']=get_img($v,'_480');
$re[$k]['img_480']=get_img($v,'_480');
$re[$k]['img_750']=get_img($v,'_750');
$re[$k]['img_240']=get_img($v,'_240');
}
}
return $re;
}

function get_img_arr($img,$c){
if(!$img){return;}
$im=explode('||',$img);
foreach($im as $k=>$v){
if($v){
$re[]=get_img($v,$c);
}
}return $re;
}


function get_img($d,$n){global $cfg;
if(!strstr($d,'|')){

if(strstr($d,'alicdn.com')){
$ext=substr($d,-4,4);
$n=str_replace('_','',$n);
if($n){
if(strstr($d,'64x64')){
return str_replace('64x64',$n.'x'.$n,$d);
}
if(strstr($d,'360x360')){
return str_replace('360x360',$n.'x'.$n,$d);
}
if(strstr($d,'60x60')){
return str_replace('60x60',$n.'x'.$n,$d);
}

if(strstr($d,'720x720')){
return str_replace('720x720',$n.'x'.$n,$d);
}


if(strstr($d,'480x480')){
return str_replace('480x480',$n.'x'.$n,$d);
}
return str_replace($ext,'',$d).'.'.$n.'x'.$n.$ext;}else{
return str_replace($ext,'',$d).$ext;
}
}


if(strstr($d,'.avif')){$d=str_replace('.avif','',$d);}
if(substr($d,0,2)=='//'){$d='https:'.$d;}
if(strstr($d,'s480x480')){$n=str_replace('_','',$n);
return str_replace('s480x480','s'.$n.'x'.$n,$d);
}

if(strstr($d,'s800x800')){$n=str_replace('_','',$n);
return str_replace('s800x800','s'.$n.'x'.$n,$d);
}
return $d;}

if(strstr($d,'||')){//获取首恶
if($n){//获取首个
$im=explode('||',$d);//print_r($im);
return get_img($im[0],$n);
}else{
$im=get_imgs($d);
return $im;
}
}
$im=explode('|',$d);
if(is_numeric($im[0])){
if($cfg['img_server']){
$num=count($cfg['img_server']);
$id=substr($im[0],-1)%$num;
//echo $id.' ';

//$id=array_rand($cfg['img_server']);

$cfg['img_path']=$cfg['img_server'][$id];
}
if(substr($cfg['img_path'],-1)=='/'){$path=$cfg['img_path'];}else{$path=$cfg['img_path'].'/';}
return $path.ceil($im[0]/1000).'/'.$im[0].$n.'.'.$im[1];
}else{return $d;}
}


function my_sql($cfg){
global $conn;
if(is_array($cfg['database'])){$cfg=$cfg['database'];}

if($cfg['type']=='mysql' or $cfg['type']=='mysqli' or !$cfg['type']){$cfg['type']='mysql';}
if(strstr($cfg['url'],'p:')){$cfg['ATTR_PERSISTENT']=1;}//长期链接
$cfg['url']=str_replace('p:','',$cfg['url']);
$dsn=$cfg['type'].':host='.$cfg['url'].';dbname='.$cfg['database'];
try {
    if($cfg['ATTR_PERSISTENT']){
    $conn = new PDO($dsn, $cfg['user'], $cfg['pass'],array(PDO::ATTR_PERSISTENT => true));//长连接
    }else{
    $conn = new PDO($dsn, $cfg['user'], $cfg['pass']);} //初始化一个PDO对象
} catch (PDOException $e) {
    die ("Error!: " . $e->getMessage() . "<br/>");
}
return $conn;
}



function db($sql,$p=[]){//查询数据
global $conn,$cfg;
$sth = $conn->prepare($sql);
if($p){
foreach($p as $k=>$v){//参数
$sth->bindValue(':'.$k, $v);
}
}
$sth->execute();
$err=$sth->errorInfo();
if($err[0]!=0){die($err[2]);}
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
$sth->closeCursor();
return $result;
while($r = $sth->fetch(PDO::FETCH_ASSOC)){$result[]=$r;}
$rows=$sth->rowCount();
$sth->closeCursor();
return $result;
}

function db1($sql,$p=[]){
global $conn,$cfg;
$sth = $conn->prepare($sql);
if($p){
foreach($p as $k=>$v){//参数
$sth->bindValue(':'.$k, $v);
}
}
$sth->execute();
$err=$sth->errorInfo();
if($err[0]!=0){die($err[2]);}
$result = $sth->fetch(PDO::FETCH_ASSOC);
$sth->closeCursor();
return $result;
}


function insert($table,$arr){
global $conn,$cfg;
if(!$arr){die('数据库插入数据为空');}
foreach($arr as $k=>$v){
if(!$ids){$ids=$k;
$vid=':'.$k;
}else{$ids.=','.$k;$vid.=',:'.$k;}
}
$sql='insert into '.$table.' ('.$ids.') VALUES ('.$vid.') ';
$sth = $conn->prepare($sql);
foreach($arr as $k=>$v){//数据
$sth->bindValue(':'.$k,$v);
}
$sth->execute();
$err=$sth->errorInfo();
if($err[0]!=0){die($err[2]);}
$lastInsertId=$conn->lastInsertId();
$sth->closeCursor();
return $lastInsertId;
}


function update($table,$arr,$where,$sql_p=[]){
global $conn,$cfg;
if(!$arr){die('更新数据为空');}
if(!$where){die('请输入更新条件');}
foreach($arr as $k=>$v){
if(!$ids){$ids=' '.$k.'=:'.$k;}else{
$ids.=' ,'.$k.'=:'.$k;
}
}
$sql='update '.$table.' set '.$ids.' '.$where;
$sth = $conn->prepare($sql);
foreach($arr as $k=>$v){//数据
$sth->bindValue(':'.$k,$v);
}
if($sql_p){
foreach($sql_p as $k=>$v){//参数
$sth->bindParam(':'.$k, $v);
}
}
$sth->execute();
$err=$sth->errorInfo();
if($err[0]!=0){die($err[2]);}
$rows=$sth->rowCount();
$sth->closeCursor();
return $rows;
}


function sql_query($sql,$p=[]){//执行
global $conn,$cfg;
$sth = $conn->prepare($sql);
$sth->execute($p);
$err=$sth->errorInfo();
if($err[0]!=0){die($err[2]);}
$rows=$sth->rowCount();
$sth->closeCursor();
return $rows;
}

function sql_error(){global $conn,$cfg;return;}

function save_file($path,$name,$str){//保存文件 save_file('目录'，‘文件名’,'字符');
if(substr($path,-1,1)!="/"){$path.='/';}
if(!file_exists($path)){mkdir($path,0700);}
$filename=$path.$name;
$handle=fopen($filename,"w");
if (fwrite($handle,$str)){return true;}else{return false;}
fclose($handle);
}

function mem(){//memcahce连接函数
@$mc = new Memcached();
$mc->addServer("localhost", 11211);
return $mc;
}


function get_days($t){//获取该月时间内日期
$start=get_time(date('Y-m-1 0:0:0',$t));//该月当天时间
$start_w=date('N',$start)-1;//当月周
$days=date('t',$start);//该月日期数
$end=get_time(date('Y-m-'.$days.' 0:0:0',$t));
$end_w=7-date('N',$end);
$n=0;
if($start_w>0){//开始的空格
for($i=1;$i<=$start_w;$i++){
$re[$n]='null';
$n++;
}
}

for($i=1;$i<=$days;$i++){
$re[$n]['d']=date('j',$start+(3600*24*($i-1)));
$re[$n]['m']=date('Ymd',$start+(3600*24*($i-1)));
$n++;
}

if($end_w>0){//结束
for($i=1;$i<=$end_w;$i++){
$re[$n]='null';
$n++;
}
}
return $re;

}

function get_age($date){
$t=get_time($date.' 0:0:0');
$age=(time()-$t)/(3600*24*365);
return floor($age);
}


function get_time($t){//获取时间
$x=explode(' ',$t);
if($x[0]){$h=explode("-",$x[0]);}else{$h=array();}
if($x[1]){$hh=explode(":",$x[1]);}else{$hh=array();}
return mktime($hh[0],$hh[1],$hh[2],$h[1],$h[2],$h[0]);
}

function date_day($d){
$s=$d-time();
if($s>0){
return ceil($s/(3600*24));
}else{return 0;}
}

function get_dis($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){
  $EARTH_RADIUS = 6370.996; // 地球半径系数
  $PI = 3.1415926;
  $radLat1 = $latitude1 * $PI / 180.0;
  $radLat2 = $latitude2 * $PI / 180.0;
  $radLng1 = $longitude1 * $PI / 180.0;
  $radLng2 = $longitude2 * $PI /180.0;
  $a = $radLat1 - $radLat2;
  $b = $radLng1 - $radLng2;
  $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
  $distance = $distance * $EARTH_RADIUS * 1000;
  if($unit==2){
    $distance = $distance / 1000;
  }
  return round($distance, $decimal);
}

function date_ff($d){
$s=time()-$d;
if($s>0){
if($s<60){return $s.'秒前';}
$fen=floor($s/60);if($fen<60){return $fen.'分钟前';}
$h=floor($s/3600);if($h<24){return $h.'小时前';}
$day=floor($s/86400);if($day<365){return $day.'天前';}
$year=floor($s/(86400*365));return $year.'年前';
}else{
$s=-$s;
if($s<60){return $s.'秒';}
$fen=floor($s/60);if($fen<60){return $fen.'分钟';}
$h=floor($s/3600);if($h<24){return $h.'小时';}
$day=floor($s/86400);if($day<365){return $day.'天';}
$year=floor($s/(86400*365));return $year.'年';

}
}

function min_get_qr($d){//获取小程序码
global $cfg;
$path='../cache/';
if($d['p']){$path=$d['p'];}
$img_path='./cache/';
if(!file_exists($path)){mkdir($path);}
$path=$path.$d['path'];$img_path=$img_path.$d['path'];
if(!file_exists($path)){mkdir($path);}
$file=$d['file'];
if(file_exists($path.$file)){return $img_path.$file;}//如果已经存在
if(!$d['wx_xcx_appid']){return;}
$token=getAccessToken($d['wx_xcx_appid'],$d['wx_xcx_secret']);  
$url='https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.$token;
$data = json_encode($d['data'],true); 
//echo $data;
$qr = send_post( $url,$data);//获取小程序码
if(strlen($qr)>100){
$newFile = fopen($path.$file,"w"); //打开文件准备写入
fwrite($newFile,$qr); //写入二进制流到文件
fclose($newFile); //关闭文件
}else{err('二维码生成失败'.$qr);}
return $img_path.$file;
}

function wx_msg($d){global $cfg;//发送公众号消息
if(!$d['touser']){return;}
$post_data = array (
  "touser"=>$d['touser'],
  "template_id"=> $d['temp_id'],
  "url"=> $d['url'],
  'topcolor'=>'#000',
  "data"=> $d['data']
);

$token=getAccessToken($cfg['appID'], $cfg['appsecret']);  
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$token;
$data = json_encode($post_data, true); 
$return = send_post( $url, $data);
return $return;
}

function min_msg($d){//小程序订阅消息发送
global $cfg;
$data['touser']=$d['openid'];
$data['template_id']=$d['template_id'];
$data['page']=$d['url'];
$data['data']=$d['data'];
if($cfg['wx_xcx_appid'] and $cfg['wx_xcx_secret']){
$token=getAccessToken ($cfg['wx_xcx_appid'], $cfg['wx_xcx_secret']);  
}else{return;}//获取接口
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=".$token;
$data = json_encode($data, true); 
$return = send_post( $url, $data);
if($return){
$return=json_decode($return,1);
}
return $return;
}

function post($url,$data) {//获取微信认证
global $cfg;
  $html = curlPost($url,$data,'');
  $output = json_decode($html, true);
  return $output;
}

function send_post( $url, $post_data ) {//发送消息
  $options = array(
    'http' => array(
      'method'  => 'POST',
      'header'  => 'Content-type:application/json',
      'content' => $post_data,
      'timeout' => 60
    )
  );
  $context = stream_context_create( $options );
  $result = file_get_contents( $url, false, $context );
  return $result;
}

function getAccessToken ($appid, $appsecret) {//获取微信认证
global $conn,$cfg,$set;
if($set['access_token'] and $set['token_end']>time()){return $set['access_token'];}
  $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
  $html = file_get_contents($url);
  $output = json_decode($html, true);
  $access_token = $output['access_token'];
  $arr['access_token']=$access_token;
  $arr['token_end']=time()+3600;
  update($cfg['e'].'set',$arr,' where id="1"');
  return $access_token;
}

function data_to_xml( $params ){
        if(!is_array($params)|| count($params) <= 0){return false;}
        $xml = "<xml>";
        foreach ($params as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
function postXmlCurl($url,$xml,$second = 30){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $data = curl_exec($ch);
        if($data){
            curl_close($ch);
            return $data;
        }else{
            $error = curl_errno($ch);
            curl_close($ch);
            echo "curl 出错，错误码:$error"."<br>";
        }
    }

   function xml_to_data($xml){
        if(!$xml){
            return false;
        }

        if (PHP_VERSION_ID < 80000) {
    libxml_disable_entity_loader(true);
}
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }


function resize_img($path,$img,$new,$ext,$widths){if(!$widths){return;}
$img_info=getimagesize($path.$img);
$img_w=$img_info[0];
$img_h=$img_info[1];
$img_type=$img_info[2];
$can=0;
if($img_type>0){
switch($img_type){
case 2:$srcImageSource = imagecreatefromjpeg($path.$img);$can++;break;
case 3:$srcImageSource = imagecreatefrompng($path.$img);$can++;break;
case 18:$srcImageSource = imagecreatefromwebp($path.$img);$can++;break;
}

}

if($can){

foreach($widths as $width){
$new_name=$new.'_'.$width;
if($img_w>=$width){
$height = ceil($width/$img_w*$img_h);
$tmpImage = imagecreatetruecolor($width,$height);
$color=imagecolorallocate($tmpImage,255,255,255);
imagecolortransparent($tmpImage,$color);
imagefill($tmpImage,0,0,$color);

if(!$srcImageSource){return 0;}
imagecopyresampled($tmpImage,$srcImageSource,0,0,0,0,$width,$height,$img_w,$img_h);
switch($img_type){
case 3:imagepng($tmpImage,$path.$new_name.'.'.$ext);break;
case 2:imagejpeg($tmpImage,$path.$new_name.'.'.$ext,100);break;
case 18:imagewebp($tmpImage,$path.$new_name.'.'.$ext,100);break;
}

}else{//如果图片小于需要尺寸
copy($path.$img,$path.$new_name.'.'.$ext);
//exec('ln '.$path.$img.' '.$path.$new_name.'.'.$ext);
}
}
}}


//打印机
/**
 * @param $orderid_all
 * @return mixed|string|void
 * 打印订单传参订单id数组
 */
function printer($orderid){
    global $cfg;
    $sql='select * from '.$cfg['e'].'order where id="'.a($orderid).'" ';
    $order=db1($sql);
    $order['date'] = date_ff($order['date']);
    if($order['yun'] == 'is_ps'){
        $order['yun'] = "配送到家";
    }elseif ($order['yun'] == 'is_zt'){
        $order['yun'] = "门店自提";
    }elseif ($order['yun'] == 'is_kd'){
        $order['yun'] = "快递";
    }
    $sql='select * from '.$cfg['e'].'print where shop_id="'.$order["shop_id"].'" ';
    $l=db1($sql);if(!$l){return '没有找到打印机';}
    $data['client_id']=$cfg['print_id'];
    $token=get_print_token();
    if(!$token){return '系统错误，请联系我们处理';}
    $data['access_token']=$token['token'];
    $data['machine_code']=$l['appid'];
    $data['content']=print_text($order);
    $data['idempotence']=0;
    $data['origin_id']=time();
    $data['sign']=$token['sign'];
    $data['id']=$token['uuid'];
    $data['timestamp']=$token['timestamp'];
    $url='https://open-api.10ss.net/print/index';
    $HTTP_headers='Content-Type:application/x-www-form-urlencoded';
    $re=curlPost($url,$data,$HTTP_headers);
    $re=json_decode($re,1);
    if($re['error']==0){
        return 'ok';
    }else{
        return $re['error_description'];
    }
}
function print_format($data){//对打印机数据进行配置
    $re='';
    foreach($data as $v){
        $r='';$x=0;
        if($v['FS2']==1){$r.='<FS2>';$x=1;}
        if($v['FS']==1){$r.='<FS>';$x=1;}
        if($v['FB']==1){$r.='<FB>';$x=1;}
        if($v['center']==1){$r.='<center>';$x=1;}
        if($v['repeat']==1){$x=1;$r.='<center>';$v['text']=str_repeat($v['text'],30);}//重复
        if($v['QR']==1){$r.='<QR>';$x=1;}
        if($v['table']){$r='';$x=1;}
        if(!$x){$r='<LR>';}
        $r.=$v['text'];

        if($v['QR']==1){$r.='</QR>\n';}
        if($v['repeat']==1){$r.='</center>\n ';}
        if($v['center']==1){$r.='</center>\n';}
        if($v['FB']==1){$r.='</FB>\n';}
        if($v['FS']==1){$r.='</FS>\n';}
        if($v['FS2']==1){$r.='</FS2>\n';}
        if(!$x){$r.='</LR>\n';}

        $re.=$r;
    }
    return $re;

}




function print_text($data){global $cfg;
    $data['shop_name'] = base64($data['shop_name']);
    $content .= "<FS><center>{$data['shop_name']}</center></FS>";
    $content .= str_repeat('.', 32);
    $content .= "订单时间:{$data['date']   } \n";
    $content .= "联系人:{$data['name']}\n";
    $content .= "手机号:{$data['phone']}\n";
    $content .= "团长:{$data['info']}\n";
    $content .= "配送方式:{$data['yun']}\n";
    $content .= "收货地址:{$data['pro']}{$data['city']}{$data['dist']}{$data['addr']}\n";
    $content .= "留言:{$data['info']}\n";
    $content .= str_repeat('*', 14) . "商品" . str_repeat("*", 14);
    $data['data']=unserialize(out($data['data']));
    $content .= "<table><tr><td>商品</td><td></td><td>数量</td></tr>";
    foreach ($data['data']['pro'] as $item) {
        $sql='select * from '.$cfg['e'].'pro where id="'.$item['id'].'" ';
        $pro=db1($sql);
        $title = base64($pro['title']);
        if($item['data']){
            //带有规格
            foreach ($item['data'] as $key => $mingxi){
                $content .= "<tr><td>{$title}</td><td>({$key})</td><td>x{$mingxi['item_']['buy']}</td></tr>";
            }

        }else{
            //不带规格
            $content .= "<tr><td>{$title}</td><td></td><td>x{$item['buy']}</td></tr>";
        }

    }
    $content .= "</table>\n";

    $content .= str_repeat('.', 32);
    $content .= "商品价格:￥{$data['price']} 共{{$data['num']}}件\n";
    $content .= "折扣:￥{$data['zk']}}\n";
    $content .= "运费:￥{$data['yun_price']}\n";
    $content .= "优惠券:￥{$data['quan_price']}\n";
    $content .= "总价:￥{$data['total']}\n";
    $content .= "********************************<FS2>   --  完 --</FS2>";
    return $content;
}


function get_print_token(){
    global $redis,$cfg;
    if($redis){
        $token=$redis->get('print_token');
        if($token){$token=unserialize(out($token));}
        if(is_array($token)){return $token;}
    }

    $time=time();
    $sign=strtolower(md5($cfg['print_id'].$time.$cfg['print_s']));
    $uuid=get_uuid4();
    $url='https://open-api.10ss.net/oauth/oauth';
    $data['client_id']=$cfg['print_id'];
    $data['grant_type']='client_credentials';
    $data['sign']=$sign;
    $data['scope']='all';
    $data['timestamp']=$time;
    $data['id']=$uuid;
    $HTTP_headers='Content-Type:application/x-www-form-urlencoded';
    $re=curlPost($url,$data,$HTTP_headers);
    if($re){
        $arr=json_decode($re,1);
        if($arr['error']==0){
            $token['token']=$arr['body']['access_token'];
            $token['uuid']=$uuid;
            $token['timestamp']=$time;
            $token['sign']=$sign;
            if($redis){
                r_set('print_token',$token,3600*24*30);
            }
            return $token;
        }else{
            err($arr['error_description']);
        }
    }
}

function get_uuid4(){
    return '00000000-0000-0000-0000-000000000000';
    return getrandstr(8).'-'.getrandstr(4).'-'.getrandstr(4).'-'.getrandstr(4).'-'.getrandstr(12);
}


function getrandstr($length){
    $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    $randStr = str_shuffle($str);//打乱字符串
    $rands= substr($randStr,0,$length);//substr(string,start,length);返回字符串的一部分
    return $rands;
}


class wechatAppPay
{
//接口API URL前缀
    const API_URL_PREFIX = 'https://api.mch.weixin.qq.com';
//下单地址URL
    const UNIFIEDORDER_URL = "/pay/unifiedorder";
//查询订单URL
    const ORDERQUERY_URL = "/pay/orderquery";
//关闭订单URL
    const CLOSEORDER_URL = "/pay/closeorder";
//公众账号ID
    private $appid;
//商户号
    private $mch_id;
//随机字符串
    private $nonce_str;
//签名
    private $sign;
//商品描述
    private $body;
//商户订单号
    private $out_trade_no;
//支付总金额
    private $total_fee;
//终端IP
    private $spbill_create_ip;
//支付结果回调通知地址
    private $notify_url;
//交易类型
    private $trade_type;
//支付密钥
    private $key;
//证书路径
    private $SSLCERT_PATH;
    private $SSLKEY_PATH;
//所有参数
    private $params = array();
    public function __construct($appid, $mch_id, $notify_url, $key)
    {
        $this->appid = $appid;
        $this->mch_id = $mch_id;
        $this->notify_url = $notify_url;
        $this->key = $key;
    }
    /**
     * 下单方法
     * @param $params 下单参数
     */
    public function unifiedOrder( $params ){
        $this->body = $params['body'];
        $this->out_trade_no = $params['out_trade_no'];
        $this->total_fee = $params['total_fee'];
        $this->trade_type = $params['trade_type'];
        $this->nonce_str = $this->genRandomString();
        $this->spbill_create_ip = $_SERVER['REMOTE_ADDR'];
        $this->params['appid'] = $this->appid;
        $this->params['mch_id'] = $this->mch_id;
        $this->params['nonce_str'] = $this->nonce_str;
        $this->params['body'] = $this->body;
        $this->params['out_trade_no'] = $this->out_trade_no;
        $this->params['total_fee'] = $this->total_fee;
        $this->params['spbill_create_ip'] = $this->spbill_create_ip;
        $this->params['notify_url'] = $this->notify_url;
        $this->params['trade_type'] = $this->trade_type;
//获取签名数据
        $this->sign = $this->MakeSign( $this->params );
        $this->params['sign'] = $this->sign;
        $xml = $this->data_to_xml($this->params);
        $response = $this->postXmlCurl($xml, self::API_URL_PREFIX.self::UNIFIEDORDER_URL);
        if( !$response ){
            return false;
        }
        $result = $this->xml_to_data( $response );
        if( !empty($result['result_code']) && !empty($result['err_code']) ){
            $result['err_msg'] = $this->error_code( $result['err_code'] );
        }
        return $result;
    }

    /**
     * 小程序 下单方法
     * @param $params
     * @return bool|mixed
     */
    public function unifiedOrder2( $params ){
        $this->body = $params['body'];
        $this->out_trade_no = $params['out_trade_no'];
        $this->total_fee = $params['total_fee'];
        $this->trade_type = $params['trade_type'];
        $this->nonce_str = $this->genRandomString();
        $this->spbill_create_ip = $_SERVER['REMOTE_ADDR'];
        $this->params['appid'] = $this->appid;
        $this->params['mch_id'] = $this->mch_id;
        $this->params['nonce_str'] = $this->nonce_str;
        $this->params['body'] = $this->body;
        $this->params['out_trade_no'] = $this->out_trade_no;
        $this->params['total_fee'] = $this->total_fee;
        $this->params['spbill_create_ip'] = $this->spbill_create_ip;
        $this->params['notify_url'] = $this->notify_url;
        $this->params['trade_type'] = $this->trade_type;
        $this->params['openid'] = $params['openid'];
//获取签名数据
        $this->sign = $this->MakeSign( $this->params );
        $this->params['sign'] = $this->sign;
        $xml = $this->data_to_xml($this->params);
        $response = $this->postXmlCurl($xml, self::API_URL_PREFIX.self::UNIFIEDORDER_URL);
        if( !$response ){
            return false;
        }
        $result = $this->xml_to_data( $response );
        if( !empty($result['result_code']) && !empty($result['err_code']) ){
            $result['err_msg'] = $this->error_code( $result['err_code'] );
        }
        return $result;
    }


    /**
     * 查询订单信息
     * @param $out_trade_no 订单号
     * @return array
     */
    public function orderQuery( $out_trade_no ){
        $this->params['appid'] = $this->appid;
        $this->params['mch_id'] = $this->mch_id;
        $this->params['nonce_str'] = $this->genRandomString();
        $this->params['out_trade_no'] = $out_trade_no;
//获取签名数据
        $this->sign = $this->MakeSign( $this->params );
        $this->params['sign'] = $this->sign;
        $xml = $this->data_to_xml($this->params);
        $response = $this->postXmlCurl($xml, self::API_URL_PREFIX.self::ORDERQUERY_URL);
        if( !$response ){
            return false;
        }
        $result = $this->xml_to_data( $response );
        if( !empty($result['result_code']) && !empty($result['err_code']) ){
            $result['err_msg'] = $this->error_code( $result['err_code'] );
        }
        return $result;
    }
    /**
     * 关闭订单
     * @param $out_trade_no 订单号
     * @return array
     */
    public function closeOrder( $out_trade_no ){
        $this->params['appid'] = $this->appid;
        $this->params['mch_id'] = $this->mch_id;
        $this->params['nonce_str'] = $this->genRandomString();
        $this->params['out_trade_no'] = $out_trade_no;
//获取签名数据
        $this->sign = $this->MakeSign( $this->params );
        $this->params['sign'] = $this->sign;
        $xml = $this->data_to_xml($this->params);
        $response = $this->postXmlCurl($xml, self::API_URL_PREFIX.self::CLOSEORDER_URL);
        if( !$response ){
            return false;
        }
        $result = $this->xml_to_data( $response );
        return $result;
    }
    /**
     *
     * 获取支付结果通知数据
     * return array
     */
    public function getNotifyData(){
//获取通知的数据
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        //$xml = file_get_contents('php://input');
        $data = array();
        if( empty($xml) ){
            return false;
        }
        $data = $this->xml_to_data( $xml );
       if( !empty($data['return_code']) ){
           if( $data['return_code'] == 'FAIL' ){
                return false;
           }
       }
        return $data;
    }
    /**
     * 接收通知成功后应答输出XML数据
     * @param string $xml
     */
    public function replyNotify(){
      /*  ksort($data);
        $buff = '';
        foreach ($data as $k => $v){
            if($k != 'sign'){
                $buff .= $k . '=' . $v . '&';
            }
        }
        $stringSignTemp = $buff . 'key=a1M5s4s6a4r8t4g2h3Md36AlJ8s7f5sd';//key为证书密钥
        $sign = strtoupper(md5($stringSignTemp));
//判断算出的签名和通知信息的签名是否一致
        if($sign == $data['sign']){
            //处理完成之后，告诉微信成功结果
            echo '<xml>
              <return_code><![CDATA[SUCCESS]]></return_code>
              <return_msg><![CDATA[OK]]></return_msg>
          </xml>';
            exit();
        }
*/
        $data['return_code'] = 'SUCCESS';
        $data['return_msg'] = 'OK';
        $xml = $this->data_to_xml( $data );
        echo $xml;
        die();
    }
    /**
     * 生成APP端支付参数
     * @param $prepayid 预支付id
     */
    public function getAppPayParams( $prepayid ){
        $data['appid'] = $this->appid;
        $data['partnerid'] = $this->mch_id;
        $data['prepayid'] = $prepayid;
        $data['package'] = 'Sign=WXPay';
        $data['noncestr'] = $this->genRandomString();
        $data['timestamp'] = time();
        $data['sign'] = $this->MakeSign( $data );
        return $data;
    }
    /**
     * 生成签名
     * @return 签名
     */
    public function MakeSign( $params ){
//签名步骤一：按字典序排序数组参数
        ksort($params);
        $string = $this->ToUrlParams($params);
//签名步骤二：在string后加入KEY
        $string = $string . "&key=".$this->key;
//签名步骤三：MD5加密
        $string = md5($string);
//签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }
    /**
     * 将参数拼接为url: key=value&key=value
     * @param $params
     * @return string
     */
     
 public   function SHA256($params){
//签名步骤一：按字典序排序数组参数
        ksort($params);
        $string = $this->ToUrlParams($params);
//签名步骤二：在string后加入KEY
        $string = $string . "&key=".$this->key;
//签名步骤三：MD5加密
$string=strtolower(hash_hmac("sha256",$string,$this->key));
        //$string = md5($string);
//签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;

}


    public function ToUrlParams( $params ){
        $string = '';
        if( !empty($params) ){
            $array = array();
            foreach( $params as $key => $value ){
                $array[] = $key.'='.$value;
            }
            $string = implode("&",$array);
        }
        return $string;
    }
    /**
     * 输出xml字符
     * @param $params 参数名称
     * return string 返回组装的xml
     **/
    public function data_to_xml( $params ){
        if(!is_array($params)|| count($params) <= 0)
        {
            return false;
        }
        $xml = "<xml>";
        foreach ($params as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    /**
     * 将xml转为array
     * @param string $xml
     * return array
     */
    public function xml_to_data($xml){
        if(!$xml){
            return false;
        }
//将XML转为array
//禁止引用外部xml实体
       if (PHP_VERSION_ID < 80000) {
    libxml_disable_entity_loader(true);
}
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }
    /**
     * 获取毫秒级别的时间戳
     */
    private static function getMillisecond(){
//获取毫秒的时间戳
        $time = explode ( " ", microtime () );
        $time = $time[1] . ($time[0] * 1000);
        $time2 = explode( ".", $time );
        $time = $time2[0];
        return $time;
    }
    /**
     * 产生一个指定长度的随机字符串,并返回给用户
     * @param type $len 产生字符串的长度
     * @return string 随机字符串
     */
    private function genRandomString($len = 32) {
        $chars = array(
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
            "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
            "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
            "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
            "3", "4", "5", "6", "7", "8", "9"
        );
        $charsLen = count($chars) - 1;
// 将数组打乱
        shuffle($chars);
        $output = "";
        for ($i = 0; $i < $len; $i++) {
            $output .= $chars[mt_rand(0, $charsLen)];
        }
        return $output;
    }
    /**
     * 以post方式提交xml到对应的接口url
     *
     * @param string $xml 需要post的xml数据
     * @param string $url url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second url执行超时时间，默认30s
     * @throws WxPayException
     */
    private function postXmlCurl($xml, $url, $useCert = false, $second = 30){
        $ch = curl_init();
//设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
//设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        if($useCert == true){
//设置证书
//使用证书：cert 与 key 分别属于两个.pem文件
            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
//curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);
            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
//curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);
        }
//post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
        $data = curl_exec($ch);
//返回结果
        if($data){
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return false;
        }
    }
    /**
     * 错误代码
     * @param $code 服务器输出的错误代码
     * return string
     */
    public function error_code( $code ){
        $errList = array(
            'NOAUTH' => '商户未开通此接口权限',
            'NOTENOUGH' => '用户帐号余额不足',
            'ORDERNOTEXIST' => '订单号不存在',
            'ORDERPAID' => '商户订单已支付，无需重复操作',
            'ORDERCLOSED' => '当前订单已关闭，无法支付',
            'SYSTEMERROR' => '系统错误!系统超时',
            'APPID_NOT_EXIST' => '参数中缺少APPID',
            'MCHID_NOT_EXIST' => '参数中缺少MCHID',
            'APPID_MCHID_NOT_MATCH' => 'appid和mch_id不匹配',
            'LACK_PARAMS' => '缺少必要的请求参数',
            'OUT_TRADE_NO_USED' => '同一笔交易不能多次提交',
            'SIGNERROR' => '参数签名结果不正确',
            'XML_FORMAT_ERROR' => 'XML格式错误',
            'REQUIRE_POST_METHOD' => '未使用post传递参数 ',
            'POST_DATA_EMPTY' => 'post数据不能为空',
            'NOT_UTF8' => '未使用指定编码格式',
        );
        if( array_key_exists( $code , $errList ) ){
            return $errList[$code];
        }
    }
}

function curl_post_ssl($url, $vars,$file_cert_pem,$file_key_pem, $second = 30, $aHeader = array())
    {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理，如果有的话
        //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //以下两种方式需选择一种

        //第一种方法，cert 与 key 分别属于两个.pem文件
        //默认格式为PEM，可以注释
        curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
//        curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert.pem');
        curl_setopt($ch,CURLOPT_SSLCERT,$file_cert_pem);
        //默认格式为PEM，可以注释
        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
//        curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/private.pem');
        curl_setopt($ch,CURLOPT_SSLKEY,$file_key_pem);

        //第二种方式，两个文件合成一个.pem文件
//        curl_setopt($ch, CURLOPT_SSLCERT, getcwd() . '/all.pem');

        if (count($aHeader) >= 1) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }


        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
        $data = curl_exec($ch);
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
//            echo "call faild, errorCode:$errorn";
            curl_close($ch);
            return false;
        }
    }
    

function xml_addChild($i,$k){
return '<'.$k.'>'.$i.'</'.$k.'>';
}

class WXBizDataCrypt
{
    private $appid;
	private $sessionKey;
 
	/**
	 * 构造函数
	 * @param $sessionKey string 用户在小程序登录后获取的会话密钥
	 * @param $appid string 小程序的appid
	 */
	public function __construct( $appid, $sessionKey)
	{
		$this->sessionKey = $sessionKey;
		$this->appid = $appid;
	}
 
 
	/**
	 * 检验数据的真实性，并且获取解密后的明文.
	 * @param $encryptedData string 加密的用户数据
	 * @param $iv string 与用户数据一同返回的初始向量
	 * @param $data string 解密后的原文
     *
	 * @return int 成功0，失败返回对应的错误码
	 */
	public function decryptData( $encryptedData, $iv, &$data )
	{
		if (strlen($this->sessionKey) != 24) {
			return ErrorCode::$IllegalAesKey;
		}
		$aesKey=base64_decode($this->sessionKey);
 
        
		if (strlen($iv) != 24) {
			return ErrorCode::$IllegalIv;
		}
		$aesIV=base64_decode($iv);
 
		$aesCipher=base64_decode($encryptedData);
 
		$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
 //print_r($result);
		$dataObj=json_decode( $result );
		if( $dataObj  == NULL )
		{
			return ErrorCode::$IllegalBuffer;
		}
		if( $dataObj->watermark->appid != $this->appid )
		{
			return ErrorCode::$IllegalBuffer;
		}
		$data = $result;
		return ErrorCode::$OK;
	}
 
}

class ErrorCode
{
	public static $OK = 0;
	public static $IllegalAesKey = -41001;
	public static $IllegalIv = -41002;
	public static $IllegalBuffer = -41003;
	public static $DecodeBase64Error = -41004;
}

class Gps
{
    const x_PI = 52.35987755982988;         // π * 3000.0 / 180.0  这里π = 3.14159265358979324
    const PI   = 3.1415926535897932384626;  // π
    const a    = 6378245.0;                 // WGS长轴半径
    const ee   = 0.00669342162296594323;    // WGS偏心率的平方
    /**
     * WGS84转GCj02(北斗转高德)
     * @param int|string $lng   经度
     * @param int|string $lat   纬度
     * @return array
     */
    static public function beiDouToAMap($lng = 0, $lat = 0)
    {
        if (self::outOfChina($lng, $lat)) {
            return array($lng, $lat);
        } else {
            $dlat      = self::transFormLat($lng - 105.0, $lat - 35.0);
            $dlng      = self::transFormLng($lng - 105.0, $lat - 35.0);
            $radlat    = $lat / 180.0 * self::PI;
            $magic     = sin($radlat);
            $magic     = 1 - self::ee * $magic * $magic;
            $sqrtmagic = sqrt($magic);
            $dlat      = ($dlat * 180.0) / ((self::a * (1 - self::ee)) / ($magic * $sqrtmagic) * self::PI);
            $dlng      = ($dlng * 180.0) / (self::a / $sqrtmagic * cos($radlat) * self::PI);
            $mglat     = $lat + $dlat;
            $mglng     = $lng + $dlng;
            return [$mglng, $mglat, 'lng' => $mglng, 'lat' => $mglat];
        }
    }
    /**
     * GCJ02 转换为 WGS84 (高德转北斗)
     * @param int|string $lng   经度
     * @param int|string $lat   纬度
     * @return array
     */
    static public function aMapToBeiDou($lng = 0, $lat = 0)
    {
        if (self::outOfChina($lng, $lat)) {
            return array($lng, $lat);
        } else {
            $dlat      = self::transFormLat($lng - 105.0, $lat - 35.0);
            $dlng      = self::transFormLng($lng - 105.0, $lat - 35.0);
            $radlat    = $lat / 180.0 * self::PI;
            $magic     = sin($radlat);
            $magic     = 1 - self::ee * $magic * $magic;
            $sqrtmagic = sqrt($magic);
            $dlat      = ($dlat * 180.0) / ((self::a * (1 - self::ee)) / ($magic * $sqrtmagic) * self::PI);
            $dlng      = ($dlng * 180.0) / (self::a / $sqrtmagic * cos($radlat) * self::PI);
            $mglat     = $lat + $dlat;
            $mglng     = $lng + $dlng;
            return array($lng * 2 - $mglng, $lat * 2 - $mglat);
        }
    }
    /**
     * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 百度转高德
     * 即 百度 转 谷歌、高德
     * @param string $bd_lon    百度经度
     * @param string $bd_lat    百度纬度
     * @return array
     */
    static public function baiDuToAMap($bd_lon = '', $bd_lat = '')
    {
        $x      = $bd_lon - 0.0065;
        $y      = $bd_lat - 0.006;
        $z      = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * self::x_PI);
        $theta  = atan2($y, $x) - 0.000003 * cos($x * self::x_PI);
        $gg_lng = $z * cos($theta);
        $gg_lat = $z * sin($theta);
        return array($gg_lng, $gg_lat);
    }
    /**
     * GCJ-02 转换为 BD-09  （火星坐标系转百度 即谷歌、高德转百度）
     * @param string $lng   经度
     * @param string $lat   纬度
     * @return array
     */
    static public function aMapToBaiDu($lng = '', $lat = '')
    {
        $z      = sqrt($lng * $lng + $lat * $lat) + 0.00002 * sin($lat * self::x_PI);
        $theta  = atan2($lat, $lng) + 0.000003 * cos($lng * self::x_PI);
        $bd_lng = $z * cos($theta) + 0.0065;
        $bd_lat = $z * sin($theta) + 0.006;
        return array($bd_lng, $bd_lat);
    }
    static private function transFormLat($lng = '', $lat = '')
    {
        $ret  = -100.0 + 2.0 * $lng + 3.0 * $lat + 0.2 * $lat * $lat + 0.1 * $lng * $lat + 0.2 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * self::PI) + 20.0 * sin(2.0 * $lng * self::PI)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lat * self::PI) + 40.0 * sin($lat / 3.0 * self::PI)) * 2.0 / 3.0;
        $ret += (160.0 * sin($lat / 12.0 * self::PI) + 320 * sin($lat * self::PI / 30.0)) * 2.0 / 3.0;
        return $ret;
    }
    static private function transFormLng($lng = 0, $lat = 0)
    {
        $ret  = 300.0 + $lng + 2.0 * $lat + 0.1 * $lng * $lng + 0.1 * $lng * $lat + 0.1 * sqrt(abs($lng));
        $ret += (20.0 * sin(6.0 * $lng * self::PI) + 20.0 * sin(2.0 * $lng * self::PI)) * 2.0 / 3.0;
        $ret += (20.0 * sin($lng * self::PI) + 40.0 * sin($lng / 3.0 * self::PI)) * 2.0 / 3.0;
        $ret += (150.0 * sin($lng / 12.0 * self::PI) + 300.0 * sin($lng / 30.0 * self::PI)) * 2.0 / 3.0;
        return $ret;
    }
    /**
     * 判断是否在国内，不在国内不做偏移
     * @param int $lng  经度
     * @param int $lat  纬度
     * @return bool
     */
    static private function outOfChina($lng = 0, $lat = 0)
    {
        return ($lng < 72.004 || $lng > 137.8347) || (($lat < 0.8293 || $lat > 55.8271) || false);
    }
}

?>